﻿using System.Collections;
using System;
using System.Collections.Generic;
using System.Reflection;
#if SCRIPTSHARP
using System.Html;
#endif

namespace Db7
{
    public static class Util
    {
        public const int NaN = -2147483647;

#if SCRIPTSHARP
        public static void Merge(object src, object dest)
        {
            
            Dictionary srcDict = Dictionary.GetDictionary(src);
            Dictionary destDict = Dictionary.GetDictionary(dest);
            IConsume consumer = dest as IConsume;
            if (consumer != null)
            {
                consumer.Consume(srcDict, destDict);
                return;
            }
            CompactJSONSerializer serializer = new CompactJSONSerializer();
            serializer.Deserialize(srcDict, destDict, dest);

            

            
            
            
            
        }

        public static void SetProperty(Dictionary destDict, string name, object val, object destObj)
        {
            Function setMethod = destDict["set_" + name.ToLowerCase()] as Function;
            object[] args = new object[] { val }; 
            setMethod.Apply(destObj, args);
        }

        public static object GetProperty(Dictionary destDict, string name, object destObj)
        {
            Function getMethod = destDict["get_" + name.ToLowerCase()] as Function;
            object[] args = new object[] {};
            object ret = getMethod.Apply(destObj, args);
            return ret;
        }

        private static Function CreateNewFunction =  new Function("return new fnx", new string[] { "fnx" });
        private static Dictionary<string, object> functionPointers = new Dictionary<string, object>();

        private static Function GetAllMembersFunction = new Function("var fns = []; for(var member in obj){var pair = []; pair[0] = member; pair[1] = obj[member]; fns[fns.length] = pair;} return fns", new string[] { "obj" });
        public static Array GetAllMembers(object obj)
        {
            Array arr = GetAllMembersFunction.Apply(Window.Self, new object[] { obj }) as Array;
            return arr;
        }

        private static Function LogToConsoleFuction = new Function("try{console.log(sMessage);}catch(e){}", new string[] { "sMessage" });

        private static Function GetAttributeFn = new Function("var val=obj[attrib];if(val!=null) return val;return obj.getAttribute(attrib);", new string[] { "obj", "attrib" });
        private static Function SetAttributeFn = new Function("obj[attrib] = value;obj.setAttribute(attrib, value);", new string[] { "obj", "attrib", "value" });

        public static void SetAttribute(object obj, string attrib, string value)
        {
            SetAttributeFn.Apply(Window.Self, new object[]{ obj, attrib, value});
        }

        public static object GetAttribute(object obj, string attrib)
        {
            return GetAttributeFn.Apply(Window.Self, new object[] { obj, attrib });
        }

        public static object CreateNew(string fn)
        {
            
            object fnP = functionPointers[fn];
            if (fnP == null)
            {
                fnP = Script.Eval(fn);
                functionPointers[fn] = fnP;

            }
            return CreateNewFunction.Apply(Window.Self, new object[] { fnP });
        }

        public static void Debug()
        {
            Script.Eval("debugger;");
        }

        public static List<string> LogMessages = new List<string>();

        
        public static void Log(string message)
        {
            LogMessages.Add(message);
            LogToConsoleFuction.Apply(Window.Self, new object[] { message });
        }

        public static string StringXString2String(Dictionary<string, string> dict, string EqSign, string Delimiter)
        {
            if (dict == null) return null;
            StringBuilder sb = new StringBuilder();
            bool first = true;
            foreach (KeyValuePair<string, string> dvp in dict)
            {
                if (first)
                {
                    first = false;
                }
                else
                {
                    sb.Append(Delimiter);
                }
                sb.Append(dvp.Key + EqSign + dvp.Value);
            }
            return sb.ToString();
        }

        public static StringSearch SubstringBetweenFirst(string text, string searchString)
        {
            int posOfSearch = text.IndexOf(searchString);
            if (posOfSearch == -1) return null;
            StringSearch ss_ = new StringSearch(posOfSearch + searchString.Length, text);
            return ss_;
        }
#else
        public static string ToServerSideQName(this string name)
        {
            return name.Substring(0, 1).ToUpper() + name.Substring(1);
        }

        public static string ServerSidePropertyNameToClientSideGetName(this PropertyInfo prop)
        {
            //find first lowercase letter ( _ considered lower case)
	        //if found, make all letters before that letter, but not adjacent to it, lower case
	        //if not found, make all letters lower case
            string name = prop.Name;
            char[] chars = name.ToCharArray();
            int posOfLowerCase = -1;
            int len = chars.Length;
            for (int i = 0; i < len; i++)
            {
                char c = chars[i];
                if ((c <= 'z' && c >= 'a') || (c == '_'))
                {
                    posOfLowerCase = i;
                    for (int j = 0; j < i - 1; j++)
                    {
                        chars[j] = char.ToLower(chars[j]);
                    }
                    break;
                }
            }
            if (posOfLowerCase == -1)
            {
                name = name.ToLower();
            }
            else
            {
                //name = chars.ToString();
                name = new string(chars);
                //enc.Convert(
            }
            return name;
        }
#endif


 

        

        
    }

    #if SCRIPTSHARP

    public class StringSearch
    {
        private int _start;
        private string _origString;

        public StringSearch(int start, string origString)
        {
            _start = start;
            _origString = origString;
        }

        public string AndFirst(string searchString)
        {
            int posOfSearch = _origString.IndexOf(searchString, _start);
            if (posOfSearch == -1) return _origString.Substr(_start);
            return _origString.Substr(_start, posOfSearch - _start);
        }
    }
    #endif
}
